package com.tengju.user.infrastructure.schedule;

import com.tengju.data.domain.model.alert.AlertEvent;
import com.tengju.data.domain.model.alert.AlertService;
import com.tengju.data.domain.model.report.DataNameEnum;
import com.tengju.data.domain.model.service.DataVersionService;
import com.tengju.user.application.archives.StarSignService;
import com.tengju.user.domain.model.sign.StarChangeNoticeRecord;
import com.tengju.user.domain.model.sign.StarChangeNoticeTypeEnum;
import com.tengju.user.domain.model.sign.StarSignInfoRepository;
import com.tengju.user.domain.shared.CastUtil;
import com.tengju.user.domain.shared.DateUtil;
import com.tengju.user.infrastructure.shared.ScheduleJobException;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.log.XxlJobLogger;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.List;

@Component
@Slf4j
public class StarInviteJob {

    @Autowired
    StarSignService starSignService;

    @Autowired
    StarSignInfoRepository starSignInfoRepository;

    @Autowired
    DataVersionService dataVersionService;

    @Autowired
    AlertService alertService;

    private final String jobName = "星级签约邀请任务";

    private final String jobKey = "starInviteJob";

    private Integer splitCount = 1000;

    @XxlJob("starInviteJob")
    public ReturnT<String> execute(String params) {
        XxlJobLogger.log("{} 开始, param:{}", jobName,params);
        log.info("{} 开始, param:{}", jobName,params);
        long start = System.currentTimeMillis();
        try {
            LocalDateTime noticeDate = LocalDateTime.now();
            if (!StringUtils.isBlank(params)) {
                noticeDate = DateUtil.dateToLocalDateTime(DateUtil.parseStringToDate(DateUtil.DATE_DAY_FORMAT,params));
            }
            noticeDate = noticeDate.withHour(0).withMinute(0).withSecond(0).withNano(0);
            int dayInt = CastUtil.castInt(DateUtil.formartLocalDateTime(DateUtil.DATE_FORMAT,noticeDate));
            if (!dataVersionService.checkStarNoticeVersion(dayInt)) {
                throw new ScheduleJobException("上游星级变更数据还未准备好！");
            }
            int count = starSignInfoRepository.countStarNotice(noticeDate, StarChangeNoticeTypeEnum.UPGRADE);
            int offset = 0;
            int successCount = 0;
            int failedCount = 0;
            while (offset <= count) {
                List<StarChangeNoticeRecord> starChangeNoticeRecordList = starSignInfoRepository.listStarNotice(
                        noticeDate,
                        StarChangeNoticeTypeEnum.UPGRADE,
                        offset,
                        splitCount);
                offset += splitCount;
                if (CollectionUtils.isEmpty(starChangeNoticeRecordList)) {
                    continue;
                }
                for (StarChangeNoticeRecord starChangeNoticeRecord : starChangeNoticeRecordList) {
                    try {
                        log.info("idCode:{},开始星级变更或者邀请！",starChangeNoticeRecord.getIdCode());
                        starSignService.inviteOrChangeStar(starChangeNoticeRecord);
                        successCount++;
                    } catch (Exception e) {
                        failedCount++;
                        log.error("星级变更或者邀请失败,idCode:{}",starChangeNoticeRecord.getIdCode(),e);
                    }
                }
            }
            dataVersionService.saveVersion(DataNameEnum.STAR_INVITE,dayInt);
            XxlJobLogger.log("星级变更或入星邀请发送结束，成功:{},失败:{}",successCount,failedCount);
        } catch (Exception e) {
            log.error("{}, jobError",jobName, e);
            AlertEvent event = new AlertEvent(jobName + "异常");
            event.addItem("异常",e.getMessage());
            alertService.alert(event);
            return ReturnT.FAIL;
        }
        XxlJobLogger.log("{}} 结束, param:{}, 耗时为:{}ms", jobName, params, System.currentTimeMillis() - start);
        return ReturnT.SUCCESS;
    }
}
